from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.utils import timezone
from typing import Dict, Any, List

from .models import (
    NotificationTemplate, Notification, NotificationPreference,
    NotificationChannel, NotificationLog
)

User = get_user_model()


class NotificationTemplateSerializer(serializers.ModelSerializer):
    """
    通知模板序列化器
    """
    created_by_name = serializers.CharField(source='created_by.username', read_only=True)
    
    class Meta:
        model = NotificationTemplate
        fields = [
            'id', 'name', 'template_type', 'subject_template',
            'content_template', 'variables', 'is_active',
            'created_by', 'created_by_name', 'created_at', 'updated_at'
        ]
        read_only_fields = ['created_by', 'created_at', 'updated_at']
    
    def validate_variables(self, value):
        """
        验证变量格式
        """
        if not isinstance(value, list):
            raise serializers.ValidationError("变量必须是列表格式")
        
        for var in value:
            if not isinstance(var, str):
                raise serializers.ValidationError("变量名必须是字符串")
        
        return value
    
    def create(self, validated_data):
        validated_data['created_by'] = self.context['request'].user
        return super().create(validated_data)


class NotificationSerializer(serializers.ModelSerializer):
    """
    通知序列化器
    """
    recipient_name = serializers.CharField(source='recipient.username', read_only=True)
    sender_name = serializers.CharField(source='sender.username', read_only=True)
    template_name = serializers.CharField(source='template.name', read_only=True)
    
    class Meta:
        model = Notification
        fields = [
            'id', 'recipient', 'recipient_name', 'sender', 'sender_name',
            'template', 'template_name', 'notification_type', 'title',
            'content', 'data', 'channels', 'priority', 'is_read',
            'read_at', 'scheduled_at', 'expires_at', 'created_at'
        ]
        read_only_fields = ['created_at', 'read_at']
    
    def validate_channels(self, value):
        """
        验证通知渠道
        """
        valid_channels = ['system', 'email', 'sms', 'push', 'webhook']
        for channel in value:
            if channel not in valid_channels:
                raise serializers.ValidationError(f"无效的通知渠道: {channel}")
        return value
    
    def validate_scheduled_at(self, value):
        """
        验证计划发送时间
        """
        if value and value <= timezone.now():
            raise serializers.ValidationError("计划发送时间必须是未来时间")
        return value


class NotificationCreateSerializer(serializers.Serializer):
    """
    创建通知序列化器
    """
    template_id = serializers.IntegerField()
    recipient_ids = serializers.ListField(
        child=serializers.IntegerField(),
        allow_empty=False
    )
    context = serializers.DictField(default=dict)
    channels = serializers.ListField(
        child=serializers.CharField(),
        default=['system']
    )
    priority = serializers.ChoiceField(
        choices=['low', 'normal', 'high', 'urgent'],
        default='normal'
    )
    scheduled_at = serializers.DateTimeField(required=False)
    expires_at = serializers.DateTimeField(required=False)
    
    def validate_template_id(self, value):
        try:
            template = NotificationTemplate.objects.get(id=value, is_active=True)
            return value
        except NotificationTemplate.DoesNotExist:
            raise serializers.ValidationError("模板不存在或已禁用")
    
    def validate_recipient_ids(self, value):
        existing_ids = User.objects.filter(id__in=value).values_list('id', flat=True)
        missing_ids = set(value) - set(existing_ids)
        if missing_ids:
            raise serializers.ValidationError(f"用户不存在: {list(missing_ids)}")
        return value


class NotificationBatchSerializer(serializers.Serializer):
    """
    批量通知序列化器
    """
    template_id = serializers.IntegerField()
    recipients = serializers.ListField(
        child=serializers.DictField(),
        allow_empty=False
    )
    context = serializers.DictField(default=dict)
    channels = serializers.ListField(
        child=serializers.CharField(),
        default=['system']
    )
    
    def validate_recipients(self, value):
        """
        验证收件人列表
        """
        for recipient in value:
            if 'user_id' not in recipient:
                raise serializers.ValidationError("每个收件人必须包含user_id")
            
            # 验证用户存在
            try:
                User.objects.get(id=recipient['user_id'])
            except User.DoesNotExist:
                raise serializers.ValidationError(f"用户不存在: {recipient['user_id']}")
        
        return value


class NotificationPreferenceSerializer(serializers.ModelSerializer):
    """
    通知偏好序列化器
    """
    user_name = serializers.CharField(source='user.username', read_only=True)
    
    class Meta:
        model = NotificationPreference
        fields = [
            'id', 'user', 'user_name', 'notification_type',
            'channel', 'is_enabled', 'settings', 'created_at', 'updated_at'
        ]
        read_only_fields = ['user', 'created_at', 'updated_at']
    
    def validate_settings(self, value):
        """
        验证设置格式
        """
        if value and not isinstance(value, dict):
            raise serializers.ValidationError("设置必须是字典格式")
        return value


class NotificationChannelSerializer(serializers.ModelSerializer):
    """
    通知渠道序列化器
    """
    
    class Meta:
        model = NotificationChannel
        fields = [
            'id', 'name', 'channel_type', 'configuration',
            'is_active', 'rate_limit', 'retry_count',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['created_at', 'updated_at']
    
    def validate_configuration(self, value):
        """
        验证配置格式
        """
        if not isinstance(value, dict):
            raise serializers.ValidationError("配置必须是字典格式")
        
        channel_type = self.initial_data.get('channel_type')
        
        # 根据渠道类型验证必需的配置项
        if channel_type == 'email':
            required_fields = ['smtp_host', 'smtp_port', 'username', 'password']
        elif channel_type == 'sms':
            required_fields = ['api_key', 'api_secret']
        elif channel_type == 'webhook':
            required_fields = ['url']
        else:
            required_fields = []
        
        for field in required_fields:
            if field not in value:
                raise serializers.ValidationError(f"缺少必需的配置项: {field}")
        
        return value


class NotificationLogSerializer(serializers.ModelSerializer):
    """
    通知日志序列化器
    """
    notification_title = serializers.CharField(source='notification.title', read_only=True)
    recipient_name = serializers.CharField(source='notification.recipient.username', read_only=True)
    
    class Meta:
        model = NotificationLog
        fields = [
            'id', 'notification', 'notification_title', 'recipient_name',
            'channel', 'status', 'sent_at', 'delivered_at',
            'error_message', 'retry_count', 'metadata'
        ]
        read_only_fields = ['sent_at', 'delivered_at']


class NotificationStatsSerializer(serializers.Serializer):
    """
    通知统计序列化器
    """
    total = serializers.IntegerField()
    unread = serializers.IntegerField()
    read = serializers.IntegerField()
    by_type = serializers.DictField()
    by_priority = serializers.DictField()


class TemplatePreviewSerializer(serializers.Serializer):
    """
    模板预览序列化器
    """
    subject = serializers.CharField()
    content = serializers.CharField()
    variables_used = serializers.ListField(child=serializers.CharField())
    missing_variables = serializers.ListField(child=serializers.CharField())